package main

import (
	"net/http"
	"log"
	"github.com/vharitonsky/iniflags"
	"flag"
)
type hijack404 struct {
	http.ResponseWriter
	R *http.Request
	Handle404 func (w http.ResponseWriter, r *http.Request) bool
}

func (h *hijack404) WriteHeader(code int) {
	if 404 == code && h.Handle404(h.ResponseWriter, h.R) {
		panic(h)
	}

	h.ResponseWriter.WriteHeader(code)
}

func Handle404(handler http.Handler, handle404 func (w http.ResponseWriter, r *http.Request) bool) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request){
		hijack := &hijack404{ ResponseWriter:w, R: r, Handle404: handle404 }

		defer func() {
			if p:=recover(); p!=nil {
				if p==hijack {
					return
				}
				panic(p)
			}
		}()

		handler.ServeHTTP(hijack, r)
	})
}

func fire404(res http.ResponseWriter, req *http.Request) bool {
//	res.Header().Add("",)
	res.Header().Set("Content-Type","text/html; charset=utf-8")
	http.ServeFile(res,req,*StaticDir+"/index.html")
//	fmt.Fprintf(res, "File not found. Please check to see if your URL is correct.");

	return true;
}

var(StaticDir = flag.String("dir", "/home/wxf/git/react-redux-jwt-auth-example/dist", "static file dir"))


// ref： http://stackoverflow.com/questions/9996767/showing-custom-404-error-page-with-standard-http-package
func main(){

	iniflags.Parse()
//	handler_statics := http.StripPrefix("/static/", http.FileServer(http.Dir("/Path_To_My_Static_Files")));

	handler_statics := http.FileServer(http.Dir(*StaticDir));

	var v_blessed_handler_statics http.Handler = Handle404(handler_statics, fire404);

//	http.Handle("/static/", v_blessed_handler_statics);
	http.Handle("/", v_blessed_handler_statics);

	// add other handlers using http.Handle() as necessary


	log.Println("server started :18080")
	if err := http.ListenAndServe(":18080", nil); err != nil{
		log.Fatal("ListenAndServe: ", err);
	}
}

